package com.group.eams.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.group.eams.mapper.AssetAllocateMapper;
import com.group.eams.mapper.FixedAssetAllMapper;
import com.group.eams.pojo.dto.*;
import com.group.eams.pojo.entity.AssetAllocate;
import com.group.eams.pojo.vo.AllocateFixedDetailListVo;
import com.group.eams.pojo.vo.AllocateFixedListVo;
import com.group.eams.pojo.vo.AssetAllocateListVo;
import com.group.eams.pojo.vo.FixedAssetListVo;
import com.group.eams.service.AssetAllocateService;
import com.group.eams.service.FixedAssetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
* @author 恩哲欣
* @description 针对表【asset_allocate(资产调拨表)】的数据库操作Service实现
* @createDate 2024-10-29 16:09:34
*/
@Service
public class AssetAllocateServiceImpl extends ServiceImpl<AssetAllocateMapper, AssetAllocate> implements AssetAllocateService{
    
    @Autowired
    private FixedAssetService fixedAssetService;
    @Autowired
    private FixedAssetAllMapper fixedAssetAllMapper;

    @Override
    public Page<AssetAllocateListVo> findAssetAllocateByWhere(AssetAllocateQueryDto assetAllocateQueryDto) {
        Page<AssetAllocateListVo> allocateListVoPage = new Page<>(assetAllocateQueryDto.getPage(),assetAllocateQueryDto.getLimit());
        return getBaseMapper().findAssetAllocateByWhere(allocateListVoPage,assetAllocateQueryDto);
    }

    @Override
    public Page<AllocateFixedListVo> findAllocateFixedByWhere(FixedAssetQueryDto fixedAssetQueryDto) {
        Page<FixedAssetListVo> fixedAssetListVoPage = fixedAssetService.findByQueryDto(fixedAssetQueryDto);
        List<AllocateFixedListVo> allocateFixedListVoList = fixedAssetListVoPage.getRecords().stream()
                .map(fixedAssetListVo ->
                        new AllocateFixedListVo(
                                fixedAssetListVo.getId(),
                                fixedAssetListVo.getAssetName(),
                                fixedAssetListVo.getNumber(),
                                fixedAssetListVo.getModel(),
                                fixedAssetListVo.getAssetCategoryName(),
                                fixedAssetListVo.getUnit(),
                                fixedAssetListVo.getAdminName(),
                                fixedAssetListVo.getUserName(),
                                fixedAssetListVo.getNowStorageLocationName()
                        ))
                .collect(Collectors.toList());
        // 修正这里，添加 records 参数
        Page<AllocateFixedListVo> allocateFixedListVoPage = new Page<>();
        allocateFixedListVoPage.setTotal(allocateFixedListVoList.size());
        allocateFixedListVoPage.setRecords(allocateFixedListVoList);
        return allocateFixedListVoPage;
    }

    @Override
    public Page<AllocateFixedDetailListVo> addAllocateFixedDetail(AssetPartDto assetPartDto) {
        List<FixedAssetListVo> fixedAssetList = fixedAssetAllMapper.fixedAssetAllListVo();
        List<FixedAssetListVo> fixedAssetListVos = fixedAssetList.stream()
                .filter(fixedAssetListVo -> assetPartDto.getAssetIds().contains(fixedAssetListVo.getId()))
                .collect(Collectors.toList());
        List<AllocateFixedDetailListVo> allocateFixedDetailListVos = fixedAssetListVos.stream().map(fixedAssetListVo ->
                new AllocateFixedDetailListVo(
                        fixedAssetListVo.getId(),
                        fixedAssetListVo.getAssetName(),
                        fixedAssetListVo.getNumber(),
                        fixedAssetListVo.getModel(),
                        fixedAssetListVo.getAssetCategoryName(),
                        fixedAssetListVo.getUnit(),
                        fixedAssetListVo.getAdminName(),
                        "",
                        fixedAssetListVo.getUserName(),
                        "",
                        fixedAssetListVo.getNowStorageLocationName(),
                        ""
                )).collect(Collectors.toList());
        Page<AllocateFixedDetailListVo> allocateFixedDetailListVoPage = new Page<>();
        allocateFixedDetailListVoPage.setTotal(allocateFixedDetailListVos.size());
        allocateFixedDetailListVoPage.setRecords(allocateFixedDetailListVos);
        return allocateFixedDetailListVoPage;
    }

    @Override
    public Page<AllocateFixedDetailListVo> findAllocateFixedDetail(ApplyNumFixedAssetQueryDto applyNumFixedAssetQueryDto) {
        List<Long> assetIds = getBaseMapper().getAssetIds(applyNumFixedAssetQueryDto.getApplicationNum());
        List<FixedAssetListVo> fixedAssetList = fixedAssetAllMapper.fixedAssetAllListVo();
        List<FixedAssetListVo> fixedAssetListVos = fixedAssetList.stream()
                .filter(fixedAssetListVo -> assetIds.contains(fixedAssetListVo.getId()))
                .collect(Collectors.toList());
        List<AllocateFixedDetailListVo> allocateFixedDetailListVos = fixedAssetListVos.stream().map(fixedAssetListVo ->
                new AllocateFixedDetailListVo(
                        fixedAssetListVo.getId(),
                        fixedAssetListVo.getAssetName(),
                        fixedAssetListVo.getNumber(),
                        fixedAssetListVo.getModel(),
                        fixedAssetListVo.getAssetCategoryName(),
                        fixedAssetListVo.getUnit(),
                        fixedAssetListVo.getAdminName(),
                        "",
                        fixedAssetListVo.getUserName(),
                        "",
                        fixedAssetListVo.getNowStorageLocationName(),
                        ""
                )).collect(Collectors.toList());
        Page<AllocateFixedDetailListVo> allocateFixedDetailListVoPage = new Page<>();
        allocateFixedDetailListVoPage.setTotal(allocateFixedDetailListVos.size());
        allocateFixedDetailListVoPage.setRecords(allocateFixedDetailListVos);
        return allocateFixedDetailListVoPage;
    }

    @Override
    public int deleteByApplicationNum(BatchDeleteIdsDto batchDeleteIdsDto) {
        // 检查 applicationNum 和 assetIds 是否都不为空，只有都不为空时才进行删除
        if (StrUtil.isEmpty(batchDeleteIdsDto.getApplicationNum()) || CollUtil.isEmpty(batchDeleteIdsDto.getAssetIds())) {
            return 0;  // 如果满足条件之一为空，则不执行删除，返回0
        }

        LambdaQueryWrapper<AssetAllocate> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        // 加入删除条件：applicationNum 非空
        lambdaQueryWrapper.eq(AssetAllocate::getApplicationNum, batchDeleteIdsDto.getApplicationNum());

        // 加入删除条件：assetIds 非空
        lambdaQueryWrapper.in(AssetAllocate::getAssetId, batchDeleteIdsDto.getAssetIds());

        // 执行删除并返回删除的记录数
        return getBaseMapper().delete(lambdaQueryWrapper);
    }

    @Override
    public int updateByApplicationNum(BatchUpdateIdsDto<AssetAllocate> batchUpdateIdsDto) {
        // 检查 applicationNum 和 assetIds 是否都不为空，只有都不为空时才进行修改
        if (StrUtil.isEmpty(batchUpdateIdsDto.getApplicationNum()) ||
                CollUtil.isEmpty(batchUpdateIdsDto.getAssetIds()) ||
                ObjectUtil.isEmpty(batchUpdateIdsDto.getT())) {
            return 0;  // 如果满足条件之一为空，则不执行修改，返回0
        }

        LambdaUpdateWrapper<AssetAllocate> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();

        // 设置查询条件
        lambdaUpdateWrapper.eq(AssetAllocate::getApplicationNum, batchUpdateIdsDto.getApplicationNum());
        lambdaUpdateWrapper.in(AssetAllocate::getAssetId, batchUpdateIdsDto.getAssetIds());

        // 获取要更新的实体对象
        AssetAllocate assetAllocate = batchUpdateIdsDto.getT();

        // 批量更新字段的方法，避免重复代码
        updateField(lambdaUpdateWrapper, assetAllocate.getStatus(), AssetAllocate::getStatus);
        updateField(lambdaUpdateWrapper, assetAllocate.getTitle(), AssetAllocate::getTitle);
        updateField(lambdaUpdateWrapper, batchUpdateIdsDto.getApplicationNum(), AssetAllocate::getApplicationNum);
        updateField(lambdaUpdateWrapper, assetAllocate.getApplicationDate(), AssetAllocate::getApplicationDate);
        updateField(lambdaUpdateWrapper, assetAllocate.getApplicantId(), AssetAllocate::getApplicantId);
        updateField(lambdaUpdateWrapper, assetAllocate.getOutDate(), AssetAllocate::getOutDate);
        updateField(lambdaUpdateWrapper, assetAllocate.getIntoDate(), AssetAllocate::getIntoDate);
        updateField(lambdaUpdateWrapper, assetAllocate.getOutDeptId(), AssetAllocate::getOutDeptId);
        updateField(lambdaUpdateWrapper, assetAllocate.getIntoDeptId(), AssetAllocate::getIntoDeptId);
        updateField(lambdaUpdateWrapper, assetAllocate.getAllocateDesc(), AssetAllocate::getAllocateDesc);
        updateField(lambdaUpdateWrapper, assetAllocate.getRemark(), AssetAllocate::getRemark);
        updateField(lambdaUpdateWrapper, assetAllocate.getFlowId(), AssetAllocate::getFlowId);
        updateField(lambdaUpdateWrapper, assetAllocate.getCurrentNode(), AssetAllocate::getCurrentNode);

        // 执行修改并返回修改的记录数
        return getBaseMapper().update(null, lambdaUpdateWrapper);
    }

    @Override
    public AssetAllocate findAllocateByNum(String applicationNum) {
        if (StrUtil.isEmpty(applicationNum)) {
            return null;
        }
        return getBaseMapper().findAllocateByNum(applicationNum);
    }

    // 使用 SFunction 进行字段更新
    private <T> void updateField(LambdaUpdateWrapper<AssetAllocate> wrapper, T value, SFunction<AssetAllocate, T> column) {
        if (value != null) {
            wrapper.set(column, value);
        }
    }

    private <T> void updateField(LambdaUpdateWrapper<AssetAllocate> wrapper, T value, T defaultValue, SFunction<AssetAllocate, T> column) {
        if (value != null && !value.equals(defaultValue)) {
            wrapper.set(column, value);
        }
    }

}
